package com.dmp.util;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisException;

import java.io.IOException;
import java.util.*;

/**
 * Jedis 书写类JedisWriteUtils 说明：这里JedisWriteUtils和JedisReadUtils的方法是一一对应的
 */
public class JedisClusterWriteUtils {

    private static Logger logger = LoggerFactory.getLogger(JedisClusterWriteUtils.class);

    private static GenericObjectPoolConfig poolConfig;
    private static JedisCluster jedisCluster;
    private static int connectionTimeout = 2000;
    private static int soTimeout = 3000;
    private static int maxRedirections = 5;
    private static int maxTotal = 30;// 最大连接数
    private static int maxIdle = 8;// 最大连接空闲数

    /**
     * 从文件名获取参数，配置redis连接
     *
     * @param fileName
     */
    public static void setJedisCluster(String fileName) {
        if (fileName == null)
            fileName = "default.properties";

        Properties props = new Properties();
        try {
            props.load(JedisClusterReadUtils.class.getClassLoader().getResourceAsStream(fileName));
        } catch (IOException e) {
            logger.error(e.getMessage());
            throw (new JedisException("can not load from file:" + fileName));
        }

        int soTimeout = Integer.parseInt(props.getProperty("redis.timeout"));
        String password = props.getProperty("redis.password");
        String jedisClusterNodes = props.getProperty("redis.path");

        Set<HostAndPort> haps = new HashSet<HostAndPort>();
        String[] paths = jedisClusterNodes.split(",");
        for (String path : paths) {
            String[] arr = path.split(":");
            if (arr.length != 2) {
                throw (new JedisException("redis address error !"));
            }
            haps.add(new HostAndPort(arr[0], Integer.valueOf(arr[1])));
        }

        JedisPoolConfig config = new JedisPoolConfig();
        // 最大连接数
        config.setMaxTotal(maxTotal);
        // 最大连接空闲数
        config.setMaxIdle(maxIdle);

        jedisCluster = new JedisCluster(haps, connectionTimeout, soTimeout, maxRedirections, config);
    }

    /**
     * 设置redis连接JedisPool
     *
     * @param jedisCluster
     */
    public static void setJedisCluster(JedisCluster jedisCluster) {
        if (null == jedisCluster) {
            throw (new JedisException("param's jedisCluster is null."));
        }
        jedisCluster = jedisCluster;
    }


    /**
     * 注意： 作为一个key value存在，很多开发者自然的使用set/get方式来使用Redis，实际上这并不是最优化的使用方法。
     * 尤其在未启用VM情况下，Redis全部数据需要放入内存，节约内存尤其重要。
     * 假如一个key-value单元需要最小占用512字节，即使只存一个字节也占了512字节。
     * 这时候就有一个设计模式，可以把key复用，几个key-value放入一个key中，value再作为一个set存入，
     * 这样同样512字节就会存放10-100倍的容量。 用于存储多个key-value的值，比如可以存储好多的person Object
     * 例子：>redis-cli 存储：redis 127.0.0.1:6379> hset personhash personId
     * personObject 获得：redis 127.0.0.1:6379> hget personhash personId
     * (就可以获得当前personId对应的person对象)
     *
     */

    /**
     * @param key
     * @param field
     * @param increment
     * @return void
     * @author sunzy
     * @date 2016年3月4日 下午5:25:36
     * @Description 为key中的域 field 的值加上增量 increment
     */
    public static Long hincrBy(String key, String field, long increment) {
        JedisCluster jedisCluster = null;
        Long value = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            value = jedisCluster.hincrBy(key.getBytes(), field.getBytes(), increment);
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedisCluster, isBroken);
        }

        return value;
    }

    /**
     * 设置缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String set(String key, String value, int cacheSeconds) {
        String result = null;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            result = jedisCluster.set(key, value);
            if (cacheSeconds != 0) {
                jedisCluster.expire(key, cacheSeconds);
            }
            logger.debug("set {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("set {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 设置缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String setObject(String key, Object value, int cacheSeconds) {
        String result = null;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            result = jedisCluster.set(getBytesKey(key), toBytes(value));
            if (cacheSeconds != 0) {
                jedisCluster.expire(key, cacheSeconds);
            }
            logger.debug("setObject {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setObject {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 设置List缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static long setList(String key, List<String> value, int cacheSeconds) {
        long result = 0;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (jedisCluster.exists(key)) {
                jedisCluster.del(key);
            }
            result = jedisCluster.rpush(key, (String[]) value.toArray());
            if (cacheSeconds != 0) {
                jedisCluster.expire(key, cacheSeconds);
            }
            logger.debug("setList {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setList {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 设置List缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static long setObjectList(String key, List<Object> value, int cacheSeconds) {
        long result = 0;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (jedisCluster.exists(getBytesKey(key))) {
                jedisCluster.del(key);
            }
            List<byte[]> list = Lists.newArrayList();
            for (Object o : value) {
                list.add(toBytes(o));
            }
            result = jedisCluster.rpush(getBytesKey(key), (byte[][]) list.toArray());
            if (cacheSeconds != 0) {
                jedisCluster.expire(key, cacheSeconds);
            }
            logger.debug("setObjectList {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setObjectList {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 向List缓存中添加值
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public static long listAdd(String key, String... value) {
        long result = 0;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            result = jedisCluster.rpush(key, value);
            logger.debug("listAdd {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("listAdd {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 向List缓存中添加值
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public static long listObjectAdd(String key, Object... value) {
        long result = 0;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            List<byte[]> list = Lists.newArrayList();
            for (Object o : value) {
                list.add(toBytes(o));
            }
            result = jedisCluster.rpush(getBytesKey(key), (byte[][]) list.toArray());
            logger.debug("listObjectAdd {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("listObjectAdd {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 设置Set缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static long setSet(String key, Set<String> value, int cacheSeconds) {
        long result = 0;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (jedisCluster.exists(key)) {
                jedisCluster.del(key);
            }
            result = jedisCluster.sadd(key, (String[]) value.toArray());
            if (cacheSeconds != 0) {
                jedisCluster.expire(key, cacheSeconds);
            }
            logger.debug("setSet {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setSet {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 设置Set缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static long setObjectSet(String key, Set<Object> value, int cacheSeconds) {
        long result = 0;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (jedisCluster.exists(getBytesKey(key))) {
                jedisCluster.del(key);
            }
            Set<byte[]> set = Sets.newHashSet();
            for (Object o : value) {
                set.add(toBytes(o));
            }
            result = jedisCluster.sadd(getBytesKey(key), (byte[][]) set.toArray());
            if (cacheSeconds != 0) {
                jedisCluster.expire(key, cacheSeconds);
            }
            logger.debug("setObjectSet {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setObjectSet {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 向Set缓存中添加值
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public static long setSetAdd(String key, String... value) {
        long result = 0;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            result = jedisCluster.sadd(key, value);
            logger.debug("setSetAdd {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setSetAdd {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 向Set缓存中添加值
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public static long setSetObjectAdd(String key, Object... value) {
        long result = 0;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            Set<byte[]> set = Sets.newHashSet();
            for (Object o : value) {
                set.add(toBytes(o));
            }
            result = jedisCluster.rpush(getBytesKey(key), (byte[][]) set.toArray());
            logger.debug("setSetObjectAdd {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setSetObjectAdd {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 设置HashMap缓存
     *
     * @param key
     * @param field
     * @param obj
     */
    public static void setHashMap(String key, String field, Object obj) {
        setHashMap(key, field, obj, 0);
    }

    /**
     * 设置HashMap缓存
     *
     * @param key
     * @param field
     * @param value
     */
    public static void setHashMap(String key, String field, String value) {
        setHashMap(key, field, value, 0);
    }

    /**
     * 设置HashMap缓存
     *
     * @param key
     * @param field
     * @param obj
     * @param cacheSeconds 超时时间，0为不超时
     */
    public static void setHashMap(String key, String field, Object obj, int cacheSeconds) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (jedisCluster.hexists(getBytesKey(key), getBytesKey(field))) {
                jedisCluster.hdel(getBytesKey(key), getBytesKey(field));
            }
            jedisCluster.hset(getBytesKey(key), getBytesKey(field), toBytes(obj));
            if (cacheSeconds != 0) {
                jedisCluster.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setHashMap {} = {}", key, field, e);
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * 设置HashMap缓存
     *
     * @param key
     * @param field
     * @param value
     * @param cacheSeconds 超时时间，0为不超时
     */
    public static void setHashMap(String key, String field, String value, int cacheSeconds) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (jedisCluster.hexists(getBytesKey(key), getBytesKey(field))) {
                jedisCluster.hdel(getBytesKey(key), getBytesKey(field));
            }
            jedisCluster.hset(key, field, value);
            if (cacheSeconds != 0) {
                jedisCluster.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setHashMap {} = {}", key, field, e);
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * 设置HashMap缓存
     *
     * @param key
     * @param field
     * @param value
     */
    public static void setHashMapString(String key, String field, String value) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (jedisCluster.hexists(getBytesKey(key), getBytesKey(field))) {
                jedisCluster.hdel(getBytesKey(key), getBytesKey(field));
            }
            jedisCluster.hset(key, field, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setHashMap {} = {}", key, field, e);
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * 设置Map缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String setMap(String key, Map<String, String> value,
                                int cacheSeconds) {
        String result = null;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (jedisCluster.exists(key)) {
                jedisCluster.del(key);
            }
            result = jedisCluster.hmset(key, value);
            if (cacheSeconds != 0) {
                jedisCluster.expire(key, cacheSeconds);
            }
            logger.debug("setMap {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setMap {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 设置Map缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String setObjectMap(String key, Map<String, Object> value,
                                      int cacheSeconds) {
        String result = null;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (jedisCluster.exists(getBytesKey(key))) {
                jedisCluster.del(key);
            }
            Map<byte[], byte[]> map = Maps.newHashMap();
            for (Map.Entry<String, Object> e : value.entrySet()) {
                map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));
            }
            result = jedisCluster.hmset(getBytesKey(key), (Map<byte[], byte[]>) map);
            if (cacheSeconds != 0) {
                jedisCluster.expire(key, cacheSeconds);
            }
            logger.debug("setObjectMap {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setObjectMap {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 向Map缓存中添加值
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public static String mapPut(String key, Map<String, String> value) {
        String result = null;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            result = jedisCluster.hmset(key, value);
            logger.debug("mapPut {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("mapPut {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 向Map缓存中添加值
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public static String mapObjectPut(String key, Map<String, Object> value) {
        String result = null;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            Map<byte[], byte[]> map = Maps.newHashMap();
            for (Map.Entry<String, Object> e : value.entrySet()) {
                map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));
            }
            result = jedisCluster.hmset(getBytesKey(key), (Map<byte[], byte[]>) map);
            logger.debug("mapObjectPut {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("mapObjectPut {} = {}", key, value, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 移除Map缓存中的值
     *
     * @param key    键
     * @param mapKey 值
     * @return
     */
    public static long mapRemove(String key, String mapKey) {
        long result = 0;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            result = jedisCluster.hdel(key, mapKey);
            logger.debug("mapRemove {}  {}", key, mapKey);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("mapRemove {}  {}", key, mapKey, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 移除Map缓存中的值
     *
     * @param key    键
     * @param mapKey 值
     * @return
     */
    public static long mapObjectRemove(String key, String mapKey) {
        long result = 0;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            result = jedisCluster.hdel(getBytesKey(key), getBytesKey(mapKey));
            logger.debug("mapObjectRemove {}  {}", key, mapKey);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("mapObjectRemove {}  {}", key, mapKey, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 删除缓存
     *
     * @param key 键
     * @return
     */
    public static long del(String key) {
        long result = 0;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (jedisCluster.exists(key)) {
                result = jedisCluster.del(key);
                logger.debug("del {}", key);
            } else {
                logger.debug("del {} not exists", key);
            }
        } catch (Exception e) {
            isBroken = true;
            logger.warn("del {}", key, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }

    /**
     * 删除缓存
     *
     * @param key 键
     * @return
     */
    public static long delObject(String key) {
        long result = 0;
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (jedisCluster.exists(getBytesKey(key))) {
                result = jedisCluster.del(getBytesKey(key));
                logger.debug("delObject {}", key);
            } else {
                logger.debug("delObject {} not exists", key);
            }
        } catch (Exception e) {
            isBroken = true;
            logger.warn("delObject {}", key, e);
        } finally {
            release(jedisCluster, isBroken);
        }
        return result;
    }


    /**
     * @param key
     * @param field
     * @param obj
     */
    public static void hsetItem(String key, String field,
                                Object obj) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            jedisCluster.hset(getBytesKey(key), getBytesKey(field), toBytes(obj));
        } catch (Exception e) {
            isBroken = true;
            logger.warn("hsetItem {}", key, e);
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * 添加Object到cache
     *
     * @param key
     * @param obj
     * @param seconds
     */
    public static void addItem(String key, Object obj, int seconds) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (seconds == 0) {
                jedisCluster.set(getBytesKey(key), toBytes(obj));
            } else {
                jedisCluster.setex(getBytesKey(key), seconds, toBytes(obj));
            }

        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * 添加Object到cache的List中
     *
     * @param key
     * @param obj
     */
    public void addItemToList(String key, Object obj) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            jedisCluster.lpushx(getBytesKey(key), toBytes(obj));
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * 添加Map到cache
     *
     * @param key
     * @param map
     */
    public void addMap(String key, Map<String, String> map) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (map != null && !map.isEmpty()) {
                for (String mapKey : map.keySet()) {
                    jedisCluster.hset(key, mapKey, map.get(mapKey));
                }
            }
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * 添加Map到cache
     *
     * @param key
     * @param map
     */
    public void addMap(String key, Map<String, String> map, int seconds) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (map != null && !map.isEmpty()) {
                for (String mapKey : map.keySet()) {
                    jedisCluster.hset(key, mapKey, map.get(mapKey));
                }
            }
            if (seconds != 0) {
                jedisCluster.expire(key, seconds);
            }
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * @param key    key
     * @param member 存储的value
     * @param score  排序字段 一般为objecId
     */
    public static void addItemToSortSet(String key, Object member, double score) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            jedisCluster.zadd(getBytesKey(key), score, toBytes(member));
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * @param key
     * @param list
     * @param scores
     */
    public static void addListToSortSet(String key, List<Object> list, List<Double> scores) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (list != null && !list.isEmpty() && scores != null
                    && !scores.isEmpty() && list.size() == scores.size()) {
                for (int i = 0; i < list.size(); i++) {
                    jedisCluster.zadd(getBytesKey(key), scores.get(i),
                            toBytes(list.get(i)));
                }
            }
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * 添加List到cache
     *
     * @param key
     * @param list
     */
    public void addList(String key, List<String> list) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (list != null && !list.isEmpty()) {
                for (String value : list) {
                    jedisCluster.lpush(key, value);
                }
            }
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * 添加Set到cache
     *
     * @param key
     * @param members
     */
    public void addSet(String key, Set<String> members) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (members != null && !members.isEmpty()) {
                for (String member : members) {
                    jedisCluster.sadd(key, member);
                }
            }
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * 添加byte[]到cache
     *
     * @param key
     * @param bytes
     */
    public void addItemByte(String key, byte[] bytes) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            if (bytes != null && bytes.length > 0) {
                jedisCluster.set(getBytesKey(key), bytes);
            }
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * 添加String到cache
     *
     * @param key
     * @param value
     */
    public void addString(String key, String value) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            jedisCluster.set(key, value);
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedisCluster, isBroken);
        }
    }

    /**
     * 删除
     *
     * @param keys
     */
    public static void del(String... keys) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        if (keys != null) {
            try {
                jedisCluster = getJedisCluster();
                jedisCluster.del(keys);
            } catch (Exception e) {
                isBroken = true;
                e.printStackTrace();
            } finally {
                release(jedisCluster, isBroken);
            }
        }
    }

    /**
     * @param key
     */
    public static void delItem(String key) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        try {
            jedisCluster = getJedisCluster();
            jedisCluster.del(getBytesKey(key));

        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedisCluster, isBroken);
        }

    }

    /**
     * 删除指定key的Set中的元素itemValue
     *
     * @param key
     * @param itemValue
     * @return
     */
    public boolean removeSetItem(String key, String itemValue) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        boolean flag = false;
        try {
            jedisCluster = getJedisCluster();
            Long result = jedisCluster.srem(key, itemValue);
            if (result == 1) {
                flag = true;
            }
        } catch (Exception e) {
            isBroken = true;
            logger.error(" removeSetItem failed:", e);
        } finally {
            release(jedisCluster, isBroken);
        }

        return flag;
    }

    /**
     * @param key
     * @return
     */
    public static boolean exists(String key) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        boolean result = false;
        try {
            jedisCluster = getJedisCluster();
            result = jedisCluster.exists(getBytesKey(key));
        } catch (Exception e) {
            isBroken = true;
            logger.error(" exists failed:", e);
        } finally {
            release(jedisCluster, isBroken);

        }
        return result;
    }

    /**
     * 判断指定key的Map中的field是否存在
     *
     * @param key
     * @param field
     * @return
     */
    public boolean isMapFieldExists(String key, String field) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        boolean result = false;
        try {
            jedisCluster = getJedisCluster();
            result = jedisCluster.hexists(key, field);
        } catch (Exception e) {
            isBroken = true;
            logger.error(" isMapFieldExists failed:", e);

        } finally {
            release(jedisCluster, isBroken);
        }

        return result;
    }

    /**
     * 判断指定key的Set中的元素itemValue是否存在
     *
     * @param key
     * @param itemValue
     * @return
     */
    public boolean isSetItemExist(String key, String itemValue) {
        JedisCluster jedisCluster = null;
        boolean isBroken = false;
        boolean flag = false;
        try {
            jedisCluster = getJedisCluster();
            flag = jedisCluster.sismember(key, itemValue);
        } catch (Exception e) {
            isBroken = true;
            logger.error(" isSetItemExist failed:", e);
        } finally {
            release(jedisCluster, isBroken);
        }

        return flag;
    }


    /**
     * 获得jedis对象
     *
     * @return
     * @throws JedisException
     */
    private static JedisCluster getJedisCluster() throws Exception {
        return jedisCluster;
    }

    /**
     * jedis销毁
     *
     * @param jedisCluster
     * @param isBroken
     */
    private static void release(JedisCluster jedisCluster, boolean isBroken) {
//        if (jedisCluster != null) {
//            try {
//                if (isBroken) {
//                    jedisCluster.close();
//                } else {
//                    jedisCluster.close();
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
    }

    /**
     * 获取byte[]类型Key
     *
     * @param object
     * @return
     */
    public static byte[] getBytesKey(Object object) {
        if (object instanceof String) {
            return StrUtils.getBytes((String) object);
        } else {
            return ObjectUtils.serialize(object);
        }
    }

    /**
     * Object转换byte[]类型
     *
     * @param object
     * @return
     */
    public static byte[] toBytes(Object object) {
        return ObjectUtils.serialize(object);
    }

    /**
     * byte[]型转换Object
     *
     * @param bytes
     * @return
     */
    public static Object toObject(byte[] bytes) {
        return ObjectUtils.unserialize(bytes);
    }

}
